﻿Namespace Dimensions
    Public Enum MetisDimensionFieldType
        ''' <summary>Any additional field</summary>
        ValueField = 0
        ''' <summary>The primary key field</summary>
        ''' <remarks>The DB field name is always ID
        ''' Only one KeyField per dimension is allowed
        ''' </remarks>
        KeyField = 1
        ''' <summary>The description field</summary>
        ''' <remarks>The DB field name is always DESCRIPTION
        ''' Only one DescriptionField per dimension is allowed
        ''' </remarks>
        DescriptionField = 2
    End Enum

    Public Class MetisDimensionField
        Implements IMetisCommonEntity

        Private _OwningDimension As MetisDimension
        Private _ID As Integer = -1
        Private _Name As String = ""
        Private _DBField As DB.DBField
        Private _Annotation As String = ""
        Private _FieldType As MetisDimensionFieldType = MetisDimensionFieldType.ValueField
        Private _NumberFormat As String = ""
        Private _ColumnWidth As Integer = 64


        Private _CreatedOn As Date = Date.Now
        Private _ModifiedOn As Date = Date.Now

        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

        Sub New(ByVal OwningDimension As MetisDimension)
            _OwningDimension = OwningDimension
            _ID = OwningDimension.MetisCore.GetTemporaryFieldID

            Dim tmpFieldCount As Integer = 0
            Do
                tmpFieldCount += 1
                _Name = String.Format(My.Resources.Metis_DimField_NewName, tmpFieldCount)
            Loop Until Not _OwningDimension.Fields.Contains(_Name)

            _DBField = New DB.DBField()
            _DBField.DBfieldName = _Name
            _FieldType = MetisDimensionFieldType.ValueField
        End Sub

        Sub New(ByVal OwningDimension As MetisDimension, ByVal ID As Integer, ByVal FieldName As String, ByVal FieldType As MetisDimensionFieldType)
            _OwningDimension = OwningDimension
            _ID = ID
            _Name = FieldName
            _DBField = New DB.DBField()
            _DBField.DBfieldName = FieldName
            _FieldType = FieldType
        End Sub

        Sub New(ByVal OwningDimension As MetisDimension, ByVal FieldID As Integer, ByVal FieldName As String, ByVal FieldType As MetisDimensionFieldType, _
                ByVal DBFieldName As String, ByVal Annotation As String, ByVal ModifiedOn As Date, ByVal CreatedOn As Date, _
                ByVal NumberFormat As String, ByVal ColWidth As Integer)
            _OwningDimension = OwningDimension
            _ID = FieldID
            _Name = FieldName
            _FieldType = FieldType

            Try
                _DBField = _OwningDimension.Table.FieldList(DBFieldName)
            Catch ex As IndexOutOfRangeException
                _DBField = New DB.DBField()
                _DBField.DBfieldName = DBFieldName
            End Try

            _Annotation = Annotation
            _ModifiedOn = ModifiedOn
            _CreatedOn = CreatedOn
            _NumberFormat = NumberFormat
            _ColumnWidth = ColWidth
        End Sub

        Public Function GetNextID() As Integer Implements IMetisCommonEntity.GetNextID
            _ID = _OwningDimension.MetisCore.GetNextFieldID
            RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("ID"))
            Return _ID
        End Function

        Public ReadOnly Property ID() As Integer Implements IMetisCommonEntity.ID
            Get
                Return _ID
            End Get
        End Property

        Public Property FieldType() As MetisDimensionFieldType
            Get
                Return _FieldType
            End Get
            Set(ByVal value As MetisDimensionFieldType)
                _FieldType = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("FieldType"))
            End Set
        End Property

        Public Property Name() As String Implements IMetisCommonEntity.Name
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                If MetisCore.IsValidFieldName(value, Core.MetisCore.MAX_NAME_LENGTH) Then
                    For Each item As MetisDimensionField In _OwningDimension.Fields
                        If Not Me.Equals(item) AndAlso value.Equals(item.Name, StringComparison.OrdinalIgnoreCase) Then
                            Throw New Exceptions.DublicateNameException(value)
                        End If
                    Next
                    _Name = value
                    RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("Name"))
                Else
                    Throw New Exceptions.InvalidNameException(value)
                End If
            End Set
        End Property

        Public Property Annotation() As String Implements IMetisCommonEntity.Annotation
            Get
                Return _Annotation
            End Get
            Set(ByVal value As String)
                _Annotation = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("Annotation"))
            End Set
        End Property

        Public Property DBFieldName() As String
            Get
                Return _DBField.DBfieldName
            End Get
            Set(ByVal value As String)
                If MetisCore.IsValidFieldName(value, Core.MetisCore.MAX_DB_NAME_LENGTH) Then
                    For Each item As MetisDimensionField In _OwningDimension.Fields
                        If Not Me.Equals(item) AndAlso value.Equals(item.DBFieldName, StringComparison.OrdinalIgnoreCase) Then
                            Throw New Exceptions.DublicateNameException(value)
                        End If
                    Next
                    _DBField.DBfieldName = value
                    RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBFieldName"))
                Else
                    Throw New Exceptions.InvalidNameException(value)
                End If
            End Set
        End Property

        Public Property DBfieldLength() As Integer
            Get
                Return _DBField.DBfieldLength
            End Get
            Set(ByVal value As Integer)
                _DBField.DBfieldLength = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldLength"))
            End Set
        End Property

        Public Property DBfieldNullable() As Boolean
            Get
                Return _DBField.DBfieldNullable
            End Get
            Set(ByVal value As Boolean)
                _DBField.DBfieldNullable = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldNullable"))
            End Set
        End Property

        Public Property DBfieldTypeAsString() As String
            Get
                Return _DBField.DBfieldTypeAsString
            End Get
            Set(ByVal value As String)
                _DBField.DBfieldTypeAsString = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldType"))
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldTypeAsString"))
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldLength"))
            End Set
        End Property

        Public Property DBfieldType() As DB.DBFieldType
            Get
                Return _DBField.DBfieldType
            End Get
            Set(ByVal value As DB.DBFieldType)
                _DBField.DBfieldType = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldType"))
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldTypeAsString"))
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldLength"))
            End Set
        End Property

        Public Property DBfieldDefault() As String
            Get
                Return _DBField.DBfieldDefault
            End Get
            Set(ByVal value As String)
                _DBField.DBfieldDefault = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("DBfieldDefault"))
            End Set
        End Property

        Public ReadOnly Property DBField() As DB.DBField
            Get
                Return _DBField
            End Get
        End Property

        Public Property NumberFormat() As String
            Get
                Return _NumberFormat
            End Get
            Set(ByVal value As String)
                _NumberFormat = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("NumberFormat"))
            End Set
        End Property

        Public Property ColumnWidth() As String
            Get
                Return _ColumnWidth
            End Get
            Set(ByVal value As String)
                _ColumnWidth = value
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("ColumnWidth"))
            End Set
        End Property

        Public Function Clone() As MetisDimensionField
            Dim tmpField As New MetisDimensionField(_OwningDimension, _ID, _Name, _FieldType)
            tmpField.Annotation = _Annotation
            tmpField.ColumnWidth = _ColumnWidth
            tmpField.NumberFormat = _NumberFormat
            Return tmpField
        End Function

        Public Overrides Function ToString() As String
            Return _Name
        End Function

        Public Function CompareTo(ByVal other As IMetisCommonEntity) As Integer Implements System.IComparable(Of IMetisCommonEntity).CompareTo
            Return String.Compare(_Name, other.Name, True)
        End Function
    End Class
End Namespace

